#include<iostream>
#include<pthread.h>
#include<unistd.h>
#include<ctime>
#include "RingQueue.hpp"
#include "Task.hpp"

using namespace std;
struct ThreadData//为线程函数封装传递多参数数据，线程只允许接收单参数
{
    RingQueue<Task>*rq;//指向环形队列的指针
    string threadname;//线程名称
};

void *Productor(void* args)
{
    ThreadData* td=static_cast<ThreadData*>(args);
    //RingQueue<Task> *rq=td->rq;//这样子也行
    int len=opers.size();
    while(true)
    {
        //生产者获取数据
        int data1=rand()%10+1;
        int data2=rand()%10;
        char op=opers[rand()%len];
        Task t(data1,data2,op);
        //生产数据
        td->rq->push(t);
        //rq->push(t);
        cout<<"Productor task done, task is:"<<t.GetTask()<<" who: "<<td->threadname<<endl;
        sleep(1);
    }
    return nullptr;
}

void *Consumer(void*args)
{
    ThreadData* td=static_cast<ThreadData*>(args);
    RingQueue<Task> *rq=td->rq;
    while(true)
    {
        Task t;//为接收队列中生产者的任务，提前准备的 “空载体”
        rq->Pop(&t);//进行消费
        t();//处理数据
        cout<<"Consumer get task, task is: "<<t.GetTask()<<" name:"<<td->threadname<<" result is: "<<t.GetResult()<<endl;
        sleep(1);
    }
    return nullptr;
}
int main()
{
    srand(time(nullptr));
    RingQueue<Task> *rq=new RingQueue<Task>(20);
    pthread_t c[5],p[3];
    for(int i=0;i<3;i++)//创建生产者线程
    {
        ThreadData*td=new ThreadData();
        td->rq=rq;
        td->threadname="Productor-"+to_string(i);
        pthread_create(p+i,nullptr,Productor,td);
    }
    for(int i=0;i<5;i++)//创建消费者线程
    {
        ThreadData*td=new ThreadData();
        td->rq=rq;
        td->threadname="Consumer-"+to_string(i);
        pthread_create(c+i,nullptr,Consumer,td);
    }
    for(int i=0;i<3;i++)//回收生产者线程
    {
        pthread_join(p[i],nullptr);
    }
    for(int i=0;i<5;i++)//回收消费者线程
    {
        pthread_join(c[i],nullptr);
    }
    return 0;
}